home *** CD-ROM | disk | FTP | other *** search
/ Delphi Developer's Kit 1996 / Delphi Developer's Kit 1996.iso / power / wordapi / capilib.pas next >
Pascal/Delphi Source File  |  1995-12-22  |  19KB  |  621 lines

  1. {$N+}
  2. {$DEFINE USE_SENDMESSAGE}  { change the "$" to a "-" if you
  3.                            don't want to use SendMessage()
  4.                            (ONLY if you're compiling a .WLL!) }
  5.  
  6. UNIT CAPILib;
  7. { Library routines to support the Word's API
  8.   translated from "C" to BPascal by M.Austermeier 100116.3455@compuserve.com
  9.   req. Borland Pascal 7.x or Delphi 1.x to compile
  10.   History:
  11.     v1.1 30.09.95
  12.       * corrected bug in Register() function that lead to Word error 5007
  13.       * integrated some Word high level functions (CAPIAddXXX) provided by
  14.         Gregory M. Sohl 75144,2600 - thanks ;-)
  15.       * made ExecuteCommand a TWordCommand method
  16.       * made TWordDlgCommand safer (s. Abstract)
  17.       * some changes in demo
  18.  
  19. "These materials were developed from a Product of Microsoft Corporation,
  20. which reserves all rights. They have been modified by Martin Austermeier"
  21. See also the disclaimer in README.TXT
  22.  
  23. }
  24.  
  25. INTERFACE
  26. USES
  27.   WdCmds, WdFid;
  28.  
  29.  
  30. CONST
  31.   T_NONE   = 0;       { TypeXXX }
  32.   T_SHORT  = 1;
  33.   T_LONG   = 2;
  34.   T_DOUBLE = 3;
  35.   T_STRING = 4;
  36.  
  37. CONST
  38.   MAX_ARGS = 34;  { MaxArgs based on largest dialog }
  39.  
  40. TYPE
  41.   TFType = Integer;  { s. T_xxx }
  42.  
  43. TYPE
  44.   TArrayDef = RECORD
  45.     cArrayDimensions : Integer;
  46.     arrayDimensions : Array[0..0] OF Byte;
  47.   END;
  48.   PArrayDef = ^TArrayDef;
  49.  
  50.   AFlag = (T0, T1, T2, T3, DataIsArray, DlgSetData, DlgGetData, bufferTooSmall);
  51.   TFlags = SET OF AFlag;
  52.  
  53.   PDoubleArray = Pointer;
  54.   PStringArray = ^PChar;
  55.  
  56.   TOperator = RECORD  { WDOPR }
  57.     dat : RECORD CASE Integer OF
  58.       0 : (vShort : Integer);
  59.       1 : (vLong : LongInt);
  60.       2 : (vDouble : Double);
  61.       3 : (vString : PChar);
  62.       4 : (Arr : PArrayDef;
  63.            ptr : RECORD CASE Boolean OF
  64.              FALSE : (DoubleArray : PDoubleArray);
  65.              TRUE : (StringArray : PStringArray);
  66.            END;
  67.           );
  68.     END;
  69.  
  70.     bufferSize : Word;
  71.     ft : RECORD CASE Boolean OF
  72.       FALSE : (flags : TFlags);  { type & flags }
  73.       TRUE : (typ : TFType);    { 2 bytes }
  74.     END;
  75.     { resvd : Byte; }
  76.     fldID : Word;
  77.   END;
  78.   POperator = ^TOperator;
  79.  
  80.  
  81. TYPE
  82.   { Input and output constants for dialog commands }
  83.   AnIOMode = (DLG_GET_DATA, DLG_SET_DATA);
  84.   TIOMode = SET OF AnIOMode;
  85.  
  86. TYPE  { DlgOption }
  87.   ADlgOption = (CMD_DEFAULTS, { GetCurValues }
  88.                 CMD_DIALOG,   { display dialog }
  89.                 CMD_ACTION,   { execute dialog }
  90.                 CMD_DLG_ACTION);  { display & exec }
  91.  
  92. TYPE
  93.   TControlBlock = RECORD
  94.     cmdID : Integer;       { *new: command ID }
  95.     retBuf : Pointer;      { *new* for automatic function return }
  96.     retBufSize : Word;     { *new* for automatic function return }
  97.     dlgIOMode : TIOMode;   { *new }
  98.     dlgOpts : ADlgOption;  { *new }
  99.     argsCount : Integer;   { cArgs (=index in args array) }
  100.     returnOp : TOperator;  { wdopReturn }
  101.     args : Array[0..MAX_ARGS-1] OF TOperator; { wdoprArgs[MaxArgs] }
  102.   END;
  103.   PControlBlock = ^TControlBlock;
  104.  
  105. TYPE
  106.   TWordCommand = OBJECT
  107.     wcb : TControlBlock;
  108.  
  109.     {----------------------------------}
  110.     CONSTRUCTOR Init(commandID : Integer;
  111.                      retType : TFType;
  112.                      retBuf : PChar;
  113.                      retBufSize : Word);
  114.     { commandID: see WDCMDS.PAS;
  115.       retType : type of function return;
  116.       retBuf : (only if retType <> T_NONE) pointer to a buffer where
  117.                 RETURNed values are to be stored (max Len=retBufSize)
  118.     }
  119.     {----------------------------------}
  120.     DESTRUCTOR Done;
  121.     {----------------------------------}
  122.     PROCEDURE AddShortParam(shortVal : Integer);     VIRTUAL;
  123.     {----------------------------------}
  124.     PROCEDURE AddLongParam(longVal : LongInt);       VIRTUAL;
  125.     {----------------------------------}
  126.     PROCEDURE AddDoubleParam(doubleVal : Double);    VIRTUAL;
  127.     {----------------------------------}
  128.     PROCEDURE AddStringParam(strP : PChar);          VIRTUAL;
  129.     {----------------------------------}
  130.     FUNCTION Execute : Integer;
  131.     { call wdCommandDispatch;
  132.       returns 0 if OK, else wdError.xx }
  133.     {----------------------------------}
  134.     FUNCTION ExecuteCommand : Boolean;
  135.     { Execute; display error message if failed }
  136.     {----------------------------------}
  137.   PRIVATE
  138.     PROCEDURE _GetResult;
  139.     { copies function result into buffer^, if available }
  140.     {----------------------------------}
  141.   END;
  142.   PWordCommand = ^TWordCommand;
  143.  
  144.  
  145.   TWordDlgCommand = OBJECT(TWordCommand)
  146.     {----------------------------------}
  147.     CONSTRUCTOR Init(commandID : Integer;
  148.                      retType : TFType;
  149.                      retBuf : PChar;
  150.                      retBufSize : Word;
  151.                      dialogOption : ADlgOption;
  152.                      fMode : TIOMode);
  153.     {----------------------------------}
  154.     PROCEDURE AddShortDlgField(fieldId : Word; shortVal : Integer);
  155.     {----------------------------------}
  156.     PROCEDURE AddLongDlgField(fieldId : Word; longVal : LongInt);
  157.     {----------------------------------}
  158.     PROCEDURE AddDoubleDlgField(fieldId : Word; doubleVal : Double);
  159.     {----------------------------------}
  160.     PROCEDURE AddStringDlgField(fieldId : Word; strP : PChar; bufSize : Word);
  161.     {----------------------------------}
  162.   PRIVATE
  163.     {----------------------------------}
  164.     PROCEDURE _SetDlgField(fieldId : Word; fType : TFType);
  165.     {----------------------------------}
  166.     { Abstract - not to be called! }
  167.     PROCEDURE AddShortParam(shortVal : Integer);     VIRTUAL;
  168.     {----------------------------------}
  169.     PROCEDURE AddLongParam(longVal : LongInt);       VIRTUAL;
  170.     {----------------------------------}
  171.     PROCEDURE AddDoubleParam(doubleVal : Double);    VIRTUAL;
  172.     {----------------------------------}
  173.     PROCEDURE AddStringParam(strP : PChar);          VIRTUAL;
  174.     {----------------------------------}
  175.   END;
  176.   PWordDlgCommand = ^TWordDlgCommand;
  177.  
  178.  
  179.   TWordArrayCommand = OBJECT(TWordCommand)
  180.     { AddStringArray; AddDoubleArray NOT IMPLEMENTED! }
  181.   END;
  182.   PWordArrayCommand = ^TWordArrayCommand;
  183.  
  184. {-------------------------------------------------------------------}
  185. FUNCTION Register(docID : Integer; functionName, description : PChar) : Word;
  186. { Register new command with Word }
  187. {-------------------------------------------------------------------}
  188. FUNCTION AddToolBar(docID: Integer; lpszToolbar: PChar): Boolean;
  189. {docID:0,1,or wll.docID; lpszToolbar:Name of ToolBar }
  190. {-------------------------------------------------------------------}
  191. FUNCTION AddButton(docID: Integer;            { (0, 1, or wll.docID) }
  192.                    lpszToolBar: Pchar;        { Name of ToolBar }
  193.                    cPosition: Integer;        { position to insert Button }
  194.                    lpszMacro: Pchar;          { Command to assotiate with Button }
  195.                    lpszFace: Pchar): Boolean; { Face of the Button (Text Only) }
  196. {-------------------------------------------------------------------}
  197. FUNCTION AddMenu(docID: Integer;
  198.                  menuName: PChar;
  199.                  position: Integer;
  200.                  menuType: Integer): Boolean;
  201. {-------------------------------------------------------------------}
  202. FUNCTION AddMenuItem(docID: Integer;
  203.                      menuName: PChar;
  204.                      menuCommand: PChar;
  205.                      menuItemText: PChar;
  206.                      position: Integer;
  207.                      menuType: Integer): Boolean;
  208. {-------------------------------------------------------------------}
  209. FUNCTION AddKey(docID: Integer; keyCode: Integer; menuCommand: PChar): Boolean;
  210. {-------------------------------------------------------------------}
  211.  
  212. IMPLEMENTATION
  213. USES
  214.   WinTypes, WinProcs;
  215.  
  216.  
  217. VAR
  218.   hWordWnd : HWnd;
  219.  
  220.  
  221. (****************************************************************************
  222.                          utility functions
  223.  ****************************************************************************)
  224. PROCEDURE ErrorBox(err : Integer; cmdID : Integer);
  225. VAR
  226.   s : Array[0..50] OF Char;
  227.   args : Array [1..2] of Word;
  228. BEGIN
  229.   args[1] := err;
  230.   args[2] := cmdId;
  231.   wvsprintf(s, 'Error #%d (cmdID=%d)', args);
  232.   MessageBox(0, s, 'CAPILIB', MB_OK);
  233. END;
  234.  
  235.  
  236. PROCEDURE Abstract; BEGIN RunError(211); END;
  237.  
  238. (****************************************************************************
  239.                              TWordCommand
  240.  ****************************************************************************)
  241. CONSTRUCTOR TWordCommand.Init(commandID : Integer;
  242.                               retType : TFType;
  243.                               retBuf : PChar;
  244.                               retBufSize : Word);
  245. BEGIN
  246.   FillChar(wcb, SizeOf(wcb), 0);
  247.  
  248.   wcb.cmdID := commandID;
  249.   wcb.returnOp.ft.typ := retType;
  250.   wcb.retBuf := retBuf;
  251.   wcb.retBufSize := retBufSize;
  252.  
  253.   IF (retType = T_STRING) THEN WITH wcb.returnOp DO BEGIN
  254.     dat.vString := retBuf;
  255.     bufferSize := retBufSize;
  256.   END;
  257. END;
  258.  
  259.  
  260. DESTRUCTOR TWordCommand.Done;
  261. BEGIN { remove VMT } END;
  262.  
  263.  
  264. PROCEDURE TWordCommand.AddShortParam(shortVal : Integer);
  265. BEGIN
  266.   WITH wcb.args[wcb.argsCount] DO BEGIN
  267.     dat.vShort := shortVal;
  268.     ft.typ := T_SHORT;
  269.   END;
  270.   Inc(wcb.argsCount);
  271. END;
  272.  
  273.  
  274. PROCEDURE TWordCommand.AddLongParam(longVal : LongInt);
  275. BEGIN
  276.   WITH wcb.args[wcb.argsCount] DO BEGIN
  277.     dat.vLong := longVal;
  278.     ft.typ := T_LONG;
  279.   END;
  280.   Inc(wcb.argsCount);
  281. END;
  282.  
  283.  
  284. PROCEDURE TWordCommand.AddDoubleParam(doubleVal : Double);
  285. BEGIN
  286.   WITH wcb.args[wcb.argsCount] DO BEGIN
  287.     dat.vDouble := doubleVal;
  288.     ft.typ := T_DOUBLE;
  289.   END;
  290.   Inc(wcb.argsCount);
  291. END;
  292.  
  293.  
  294. PROCEDURE TWordCommand.AddStringParam(strP : PChar);
  295. BEGIN
  296.   WITH wcb.args[wcb.argsCount] DO BEGIN
  297.     dat.vString := strP;
  298.     ft.typ := T_STRING;
  299.   END;
  300.   Inc(wcb.argsCount);
  301. END;
  302.  
  303.  
  304. { AddStringArray; AddDoubleArray NOT IMPLEMENTED! }
  305.  
  306.  
  307. PROCEDURE TWordCommand._GetResult;
  308. BEGIN
  309.   WITH wcb DO BEGIN
  310.     IF (returnOp.ft.typ = T_NONE)  { no function result }
  311.     OR (returnOp.ft.typ = T_STRING) { unnecessary with T_STRING }
  312.     OR (retBuf = NIL)  { no return buffer provided }
  313.     THEN
  314.       Exit;
  315.  
  316.     Move (returnOp.dat, retBuf^, retBufSize);  { copy result to buffer }
  317.   END;
  318. END;
  319.  
  320.  
  321. {$IFNDEF USE_SENDMESSAGE *********************************************}
  322.  
  323. FUNCTION WdCommandDispatch(commandId,
  324.                            dlgOptions,
  325.                            cArgs : Integer;
  326.                            operators : POperator;
  327.                            ret : POperator) : Integer;
  328. FAR; EXTERNAL 'WINWORD';
  329.  
  330.  
  331. FUNCTION TWordCommand.Execute : Integer;
  332. VAR
  333.   retP : POperator;
  334.   ret : Integer;
  335. BEGIN
  336.   WITH wcb DO BEGIN
  337.     IF (returnOp.ft.typ <> T_NONE) THEN
  338.       retP := @returnOp
  339.     ELSE
  340.       retP := NIL;
  341.  
  342.     ret :=
  343.       WdCommandDispatch(cmdId,
  344.                      Integer(dlgOpts),
  345.                      argsCount,
  346.                      @args,
  347.                      retP);
  348.     IF (ret = 0) THEN
  349.       _GetResult;
  350.     Execute := ret;
  351.  
  352.   END;
  353. END;
  354.  
  355.  
  356. {$ELSE (USE_SENDMESSAGE; Word is to be called from .EXE via Sendmessage()) *** }
  357.  
  358.  
  359. FUNCTION TWordCommand.Execute : Integer;
  360. { call wdCommandDispatch via SendMessage
  361.   (takes the same time; avoids stack problems when called
  362.   from your .EXE instead of a .WLL);
  363.   returns 0 if OK, else wdError.xx }
  364. CONST
  365.   WM_USER = $0400;
  366.   WM_WORD_CAPI = WM_USER + $0300;
  367.  
  368.   WINWORD_CLASS = 'OpusApp';
  369. VAR
  370.   msg : RECORD
  371.     cmdID : Integer;
  372.     dlgOpts : Integer;
  373.     cArgs : Integer;
  374.     lpwdoprArgs,
  375.     lpwdoprReturn : PControlBlock;
  376.   END;
  377.   ret : Integer;
  378. BEGIN
  379.   { get hWordWnd }
  380.   IF NOT IsWindow(hWordWnd) THEN
  381.     hWordWnd := FindWindow(WINWORD_CLASS, NIL);
  382.  
  383.   IF (hWordWnd = 0) THEN BEGIN
  384.     ret := 5031;  { wdError.errCAPICommandFailed }
  385.   END ELSE WITH wcb DO BEGIN
  386.     msg.cmdID := cmdId;
  387.     msg.dlgOpts := Integer(dlgOpts);
  388.     msg.cArgs := argsCount;
  389.     msg.lpwdoprArgs := @args;
  390.     IF (returnOp.ft.typ <> T_NONE) THEN
  391.       msg.lpwdoprReturn := @returnOp
  392.     ELSE
  393.       msg.lpwdoprReturn := NIL;
  394.  
  395.     ret := SendMessage(hWordWnd, WM_WORD_CAPI, 0, LongInt(@msg));
  396.     IF (ret = 0) THEN
  397.       _GetResult;
  398.   END;
  399.   Execute := ret;
  400. END;
  401. {$ENDIF USE_SENDMESSAGE **************************************************}
  402.  
  403.  
  404. FUNCTION TWordCommand.ExecuteCommand : Boolean;
  405. VAR
  406.   i : Integer;
  407. BEGIN
  408.   i := Execute;         { Execute the command }
  409.  
  410.   IF (i <> 0) THEN
  411.     ErrorBox(i, wcb.cmdId);  { display error }
  412.  
  413.   ExecuteCommand := (i = 0);
  414. END;
  415.  
  416.  
  417. (*************************************************************************
  418.                            TWordDlgCommand
  419.  *************************************************************************)
  420. CONSTRUCTOR TWordDlgCommand.Init(commandID : Integer;
  421.                  retType : TFType;
  422.                  retBuf : PChar;
  423.                  retBufSize : Word;
  424.                  dialogOption : ADlgOption;
  425.                  fMode : TIOMode);
  426. BEGIN
  427.   INHERITED Init(commandID, retType, retBuf, retBufSize);
  428.   wcb.dlgOpts := dialogOption;
  429.   wcb.dlgIOMode := fMode;
  430. END;
  431.  
  432.  
  433. PROCEDURE TWordDlgCommand.AddShortParam(shortVal : Integer);
  434. BEGIN Abstract; END;  { not valid with dialog commands! }
  435.  
  436. PROCEDURE TWordDlgCommand.AddLongParam(longVal : LongInt);
  437. BEGIN Abstract; END;  { not valid with dialog commands! }
  438.  
  439. PROCEDURE TWordDlgCommand.AddDoubleParam(doubleVal : Double);
  440. BEGIN Abstract; END;  { not valid with dialog commands! }
  441.  
  442. PROCEDURE TWordDlgCommand.AddStringParam(strP : PChar);
  443. BEGIN Abstract; END;  { not valid with dialog commands! }
  444.  
  445.  
  446. PROCEDURE TWordDlgCommand._SetDlgField(fieldId : Word; fType : TFType);
  447. BEGIN
  448.   WITH wcb.args[wcb.argsCount] DO BEGIN
  449.     ft.typ := fType;
  450.     fldId := fieldId;
  451.     IF (DLG_GET_DATA IN wcb.dlgIOMode) THEN
  452.       Include(ft.flags, DlgGetData);
  453.     IF (DLG_SET_DATA IN wcb.dlgIOMode) THEN
  454.       Include(ft.flags, DlgSetData);
  455.   END;
  456. END;
  457.  
  458.  
  459. PROCEDURE TWordDlgCommand.AddShortDlgField(fieldId : Word; shortVal : Integer);
  460. BEGIN
  461.   wcb.args[wcb.argsCount].dat.vShort := shortVal;
  462.   _SetDlgField(fieldId, T_SHORT);
  463.   Inc(wcb.argsCount);
  464. END;
  465.  
  466.  
  467. PROCEDURE TWordDlgCommand.AddLongDlgField(fieldId : Word; longVal : LongInt);
  468. BEGIN
  469.   wcb.args[wcb.argsCount].dat.vLong := longVal;
  470.   _SetDlgField(fieldId, T_LONG);
  471.   Inc(wcb.argsCount);
  472. END;
  473.  
  474.  
  475. PROCEDURE TWordDlgCommand.AddDoubleDlgField(fieldId : Word; doubleVal : Double);
  476. BEGIN
  477.   wcb.args[wcb.argsCount].dat.vDouble := doubleVal;
  478.   _SetDlgField(fieldId, T_DOUBLE);
  479.   Inc(wcb.argsCount);
  480. END;
  481.  
  482.  
  483. PROCEDURE TWordDlgCommand.AddStringDlgField(fieldId : Word; strP : PChar; bufSize : Word);
  484. BEGIN
  485.   wcb.args[wcb.argsCount].dat.vString := strP;
  486.   _SetDlgField(fieldId, T_STRING);
  487.   wcb.args[wcb.argsCount].bufferSize := bufSize;
  488.   Inc(wcb.argsCount);
  489. END;
  490.  
  491.  
  492. (*************************************************************************
  493.                       High Level Word Functions
  494.  *************************************************************************)
  495. FUNCTION Register(docID : Integer; functionName, description : PChar) : Word;
  496. VAR
  497.   wcmd : TWordCommand;
  498. BEGIN
  499.   wcmd.Init(wdAddCommand, T_NONE, NIL, 0);
  500.   wcmd.AddShortParam(docID);
  501.   wcmd.AddStringParam(functionName);
  502.   IF (Assigned(description)) THEN
  503.     wcmd.AddStringParam(description);
  504.  
  505.   Register := wcmd.Execute;
  506.   wcmd.Done;
  507. END;
  508.  
  509.  
  510. { Implemented 09/1995 }
  511. { ******* CAPIAdd ToolBar ******* }
  512. FUNCTION AddToolBar(docID: Integer; lpszToolbar: PChar): Boolean;
  513. VAR
  514.   wcmd: TWordDlgCommand;
  515. BEGIN
  516.   wcmd.Init(wdNewToolbar, T_NONE, NIL, 0, CMD_ACTION, [DLG_SET_DATA]);
  517.   wcmd.AddStringDlgField(fidName, lpszToolBar, 0); {Name of ToolBar}
  518.   wcmd.AddShortDlgField(fidContext, docID);    {(0, 1, or docID)}
  519.  
  520.   AddToolBar := wcmd.ExecuteCommand;
  521.  
  522.   wcmd.Done;
  523. END;
  524.  
  525.  
  526. { ********** CAPIAddButton ******** }
  527. FUNCTION AddButton(docID: Integer; lpszToolBar: Pchar; cPosition: Integer; lpszMacro: Pchar; lpszFace: Pchar): Boolean;
  528. VAR
  529.   wcmd: TWordCommand;
  530. BEGIN
  531.   wcmd.Init(wdAddButton, T_NONE, NIL, 0);
  532.  
  533.   wcmd.AddStringParam(lpszToolBar);      {Name of ToolBar}
  534.   wcmd.AddShortParam(cPosition);         {position to insert Button}
  535.   wcmd.AddShortParam(1);
  536.   wcmd.AddStringParam(lpszMacro);        {Command to assotiate with Button}
  537.   wcmd.AddStringParam(lpszFace);         {Face of the Button (Text Only)}
  538.   wcmd.AddShortParam(docID);             {(0, 1, or docID)}
  539.  
  540.   AddButton := wcmd.ExecuteCommand;
  541.  
  542.   wcmd.Done;
  543. END;
  544.  
  545.  
  546. { ********** CAPIAddMenu ********* }
  547. FUNCTION AddMenu(docID: Integer;
  548.                  menuName: PChar;
  549.                  position: Integer;
  550.                  menuType: Integer): Boolean;
  551. VAR
  552.   wcmd: TWordDlgCommand;
  553. BEGIN
  554.   wcmd.Init(wdToolsCustomizeMenuBar, T_NONE, NIL, 0, CMD_ACTION, [DLG_SET_DATA]);
  555.   wcmd.AddStringDlgField(fidMenuText, menuName,0); {Name of Menu}
  556.   wcmd.AddShortDlgField(fidPosition, position);    {position of new Menu}
  557.   wcmd.AddShortDlgField(fidAdd, 1);
  558.   wcmd.AddShortDlgField(fidMenuType, menuType);    {Type of Menu}
  559.   wcmd.AddShortDlgField(fidContext, docID);
  560.  
  561.   AddMenu := wcmd.ExecuteCommand;
  562.  
  563.   wcmd.Done;
  564. END;
  565.  
  566.  
  567. { ********** CAPIAddMenuItem ********* }
  568. FUNCTION AddMenuItem(docID: Integer;
  569.                      menuName: PChar;
  570.                      menuCommand: PChar;
  571.                      menuItemText: PChar;
  572.                      position: Integer;
  573.                      menuType: Integer): Boolean;
  574.  
  575. VAR
  576.   wcmd: TWordDlgCommand;
  577.  
  578. BEGIN
  579.   wcmd.Init(wdToolsCustomizeMenus, T_NONE, NIL, 0, CMD_ACTION, [DLG_SET_DATA]);
  580.   wcmd.AddShortDlgField(fidContext, docID);            { (0, 1, or docID)}
  581.   wcmd.AddStringDlgField(fidMenu, menuName, 0);        {Name of menu}
  582.   wcmd.AddStringDlgField(fidName, menuCommand, 0);     {Command to Add}
  583.   wcmd.AddStringDlgField(fidMenuText, menuItemText,0); {Menu Item text}
  584.   wcmd.AddShortDlgField(fidPosition, position);        {position in Menu}
  585.   wcmd.AddShortDlgField(fidMenuType, menuType);        {Type of the Menu}
  586.   wcmd.AddShortDlgField(fidCategory, 1);
  587.   wcmd.AddShortDlgField(fidAdd, 1);
  588.  
  589.   AddMenuItem := wcmd.ExecuteCommand;
  590.  
  591.   wcmd.Done;
  592. END;
  593.  
  594.  
  595. { ********** CAPIAddKey ********* }
  596. FUNCTION AddKey(docID: Integer; keyCode: Integer; menuCommand: PChar): Boolean;
  597. VAR
  598.   wcmd: TWordDlgCommand;
  599. BEGIN
  600.   wcmd.Init(wdToolsCustomizeKeyboard, T_NONE, NIL, 0, CMD_ACTION, [DLG_SET_DATA]);
  601.   wcmd.AddShortDlgField(fidKeyCode, keyCode);     { Key Combo to be set}
  602.   wcmd.AddShortDlgField(fidCategory, 1);
  603.   wcmd.AddStringDlgField(fidName, menuCommand, 0);   {Command to Assign to Key}
  604.   wcmd.AddShortDlgField(fidAdd, 1);
  605.   wcmd.AddShortDlgField(fidContext, docID);       { (0, 1, or docID)}
  606.  
  607.   AddKey := wcmd.ExecuteCommand;
  608.   wcmd.Done;
  609. END;
  610.  
  611.  
  612.  
  613. (************************************************************************
  614.                                 Unit Init
  615.  ************************************************************************)
  616. BEGIN
  617.   hWordWnd := 0;
  618. END.
  619.  
  620.  
  621.